home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ue312src.zip / SCREEN.C < prev    next >
C/C++ Source or Header  |  1993-04-06  |  13KB  |  526 lines

  1. /*    SCREEN.C:    Screen manipulation commands
  2.             for MicroEMACS 3.12
  3.             written by Daniel Lawrence
  4. */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "eproto.h"
  9. #include        "edef.h"
  10. #include    "elang.h"
  11.  
  12. #if    0
  13. dumpscreens(msg)
  14.  
  15. char *msg;
  16.  
  17. {
  18.     SCREEN *sp;
  19.  
  20.     printf("<%s>\n", msg);
  21.     sp = first_screen;
  22.     while (sp != (SCREEN *)NULL) {
  23.         printf("%lu - [%s] %d/%d to %d/%d \n", sp, sp->s_screen_name,
  24.         sp->s_roworg, sp->s_colorg, sp->s_nrow, sp->s_ncol);
  25.         sp = sp->s_next_screen;
  26.     }
  27.     printf("   0     -   [EOL]\n");
  28.     tgetc();
  29. }
  30. #endif
  31.  
  32. #if    WINDOW_TEXT
  33. /* Redraw given screen and all screens behind it */
  34.  
  35. void PASCAL NEAR refresh_screen(sp)
  36.  
  37. SCREEN *sp;    /* screen image to refresh */
  38.  
  39. {
  40.     /* if we are suppressing redraws */
  41.     if (gflags & GFSDRAW)
  42.         return;
  43.  
  44.     /* at end of list, do nothing */
  45.     if (sp == (SCREEN *)NULL)
  46.         return;
  47.  
  48.     /* if first refresh, erase the page */
  49.     if (sp == first_screen) {
  50.         (*term.t_clrdesk)();
  51.         if (sp->s_next_screen == (SCREEN *)NULL)
  52.             sgarbf = TRUE;
  53.     }
  54.  
  55.     /* if there are others below, defer to them first */
  56.     if (sp->s_next_screen)
  57.         refresh_screen(sp->s_next_screen);
  58.  
  59.     select_screen(sp, FALSE);
  60.     update(TRUE);
  61. }
  62. #endif
  63.  
  64. /*    This command takes the last window in the linked window list,
  65.     which is visibly rearmost, and brings it to front. It is bound
  66.     to A-N on machines with an ALT key
  67. */
  68.  
  69. PASCAL NEAR cycle_screens(f, n)
  70.  
  71. int f,n;    /* prefix flag and argument */
  72.  
  73. {
  74.     SCREEN *sp;        /* ptr to screen to switch to */
  75.  
  76.     /* find the last screen */
  77.     sp = first_screen;
  78.     while (sp->s_next_screen != (SCREEN *)NULL)
  79.         sp = sp->s_next_screen;
  80.  
  81.     /* and make this screen current */
  82.     return(select_screen(sp, TRUE));
  83. }
  84.  
  85. PASCAL NEAR find_screen(f, n)
  86.  
  87. int f,n;    /* prefix flag and argument */
  88.  
  89. {
  90.     char scr_name[NSTRING];    /* buffer to hold screen name */
  91.     SCREEN *sp;        /* ptr to screen to switch to */
  92.     int result;
  93.  
  94.     /* get the name of the screen to switch to */
  95.     if ((result = mlreply(TEXT242, scr_name, NSTRING)) != TRUE) {
  96.         /* "Find Screen: " */
  97.             return result;
  98.         }
  99.     sp = lookup_screen(scr_name);
  100.  
  101.     if (sp == (SCREEN *)NULL) {
  102.  
  103.         /* save the current dot position in the buffer info
  104.            so the new screen will start there! */
  105.         curbp->b_dotp = curwp->w_dotp;
  106.         curbp->b_doto = curwp->w_doto;
  107.  
  108.         /* screen does not exist, create it */
  109.         sp = init_screen(scr_name, curbp);
  110.     }
  111.  
  112.     /* and make this screen current */
  113.     return(select_screen(sp, TRUE));
  114. }
  115.  
  116. PASCAL NEAR free_screen(sp)    /* free all resouces associated with a screen */
  117.  
  118. SCREEN *sp;    /* screen to dump */
  119.  
  120. {
  121.     register int cmark;    /* mark ordinal index */
  122.     register WINDOW *wp;    /* ptr to window to free */
  123.     register WINDOW *tp;    /* temp window pointer */
  124.  
  125.     /* first, free the screen's windows */
  126.     wp = sp->s_first_window;
  127.     while (wp) {
  128.         if (--wp->w_bufp->b_nwnd == 0) {
  129.             wp->w_bufp->b_dotp  = wp->w_dotp;
  130.             wp->w_bufp->b_doto  = wp->w_doto;
  131.             for (cmark = 0; cmark < NMARKS; cmark++) {
  132.                 wp->w_bufp->b_markp[cmark] = wp->w_markp[cmark];
  133.                 wp->w_bufp->b_marko[cmark] = wp->w_marko[cmark];
  134.             }
  135.             wp->w_bufp->b_fcol  = wp->w_fcol;
  136.         }
  137.  
  138.         /* on to the next window, free this one */
  139.         tp = wp->w_wndp;
  140.         free((char *) wp);
  141.         wp = tp;
  142.     }
  143.  
  144. #if    WINDOW_MSWIN
  145.     term.t_delscr(sp);
  146. #endif
  147.     /* and now, free the screen struct itself */
  148.     free(sp->s_screen_name);
  149.     free((char *) sp);
  150. }
  151.  
  152. PASCAL NEAR unlist_screen(sp)
  153.  
  154. SCREEN *sp;         /* screen to remove from the list */
  155. {
  156.     SCREEN *last_scr;    /* screen previous to one to delete */
  157.  
  158.     last_scr = first_screen;
  159.     while (last_scr) {
  160.         if (last_scr->s_next_screen == sp)
  161.             break;
  162.         last_scr = last_scr->s_next_screen;
  163.     }
  164.     last_scr->s_next_screen = sp->s_next_screen;
  165. }
  166.  
  167. PASCAL NEAR delete_screen(f, n)
  168.  
  169. int f,n;    /* prefix flag and argument */
  170.  
  171. {
  172.     char scr_name[NSTRING];    /* buffer to hold screen name */
  173.     SCREEN *sp;        /* ptr to screen to switch to */
  174.     int result;
  175.  
  176.     /* get the name of the screen to delete */
  177.     if ((result = mlreply(TEXT243, scr_name, NSTRING)) != TRUE) {
  178.         /* "Delete Screen: " */
  179.             return result;
  180.     } 
  181.     sp = lookup_screen(scr_name);
  182.  
  183.     /* make sure it exists... */
  184.     if (sp == (SCREEN *)NULL) {
  185.         mlwrite(TEXT240);   /* "[No such screen]" */
  186.         return(FALSE);
  187.     }
  188.  
  189.     /* it can't be current... */
  190.     if (sp == first_screen) {
  191.         mlwrite(TEXT241);   /* "%%Can't delete current screen" */
  192.         return(FALSE);
  193.     }
  194.  
  195.     unlist_screen(sp);
  196.     free_screen(sp);
  197. #if    WINDOW_TEXT
  198.     refresh_screen(first_screen);
  199. #endif
  200.     return(TRUE);
  201. }
  202.  
  203. /* this function initializes a new screen.... */
  204.  
  205. SCREEN *PASCAL NEAR init_screen(scr_name, scr_buf)
  206.  
  207. char *scr_name;        /* screen name */
  208. BUFFER *scr_buf;    /* buffer to place in first window of screen */
  209.  
  210. {
  211.     int cmark;        /* current mark to initialize */
  212.     SCREEN *sp;        /* pointer to allocated screen */
  213.     SCREEN *last_sp;    /* pointer to last screen */
  214.     WINDOW *wp;        /* ptr to first window of new screen */
  215.  
  216.     /* allocate memory for this screen */
  217.     sp = (SCREEN *)malloc(sizeof(SCREEN));
  218.     if (sp == (SCREEN *)NULL)
  219.         return(sp);
  220.  
  221.     /* set up this new screens fields! */
  222.     sp->s_next_screen = (SCREEN *)NULL;
  223.     sp->s_screen_name = copystr(scr_name);
  224. #if     WINDOW_MSWIN
  225.     if (term.t_newscr (sp) != TRUE) {       /* failed */
  226.         free ((void *)sp);
  227.         return ((SCREEN *)NULL);
  228.     }
  229.     /* ... in MSWIN, the s_nrow/ncol etc... values are kept up to
  230.        date by vtinitscr; besides, term entries may actually match
  231.        the first_screen instead of the new screen */
  232.     term.t_roworg = sp->s_roworg;
  233.     term.t_colorg = sp->s_colorg;
  234.     term.t_nrow = sp->s_nrow;
  235.     term.t_ncol = sp->s_ncol;
  236. #else
  237.     sp->s_roworg = term.t_roworg;
  238.     sp->s_colorg = term.t_colorg;
  239.     sp->s_nrow = term.t_nrow;
  240.     sp->s_ncol = term.t_ncol;
  241. #endif
  242.  
  243.     /* allocate its first window */
  244.     wp = (WINDOW *)malloc(sizeof(WINDOW));
  245.     if (wp == (WINDOW *)NULL) {
  246.         free((char *)sp);
  247.         return((SCREEN *)NULL);
  248.     }
  249.     sp->s_first_window = sp->s_cur_window = wp;
  250.  
  251.     /* and setup the windows info */
  252.     wp->w_wndp = NULL;
  253.     wp->w_bufp = scr_buf;
  254.     scr_buf->b_nwnd += 1;    
  255.     wp->w_linep = scr_buf->b_linep;
  256.  
  257.     /* position us at the buffers dot */
  258.     wp->w_dotp  = scr_buf->b_dotp;
  259.     wp->w_doto  = scr_buf->b_doto;
  260.  
  261.     /* set all the marks to UNSET */
  262.     for (cmark = 0; cmark < NMARKS; cmark++) {
  263.         wp->w_markp[cmark] = NULL;
  264.         wp->w_marko[cmark] = 0;
  265.     }
  266.     wp->w_toprow = 0;
  267. #if    COLOR
  268.     /* initalize colors to global defaults */
  269.     wp->w_fcolor = gfcolor;
  270.     wp->w_bcolor = gbcolor;
  271. #endif
  272.     wp->w_fcol = 0;
  273. #if WINDOW_MSWIN
  274.     wp->w_ntrows = sp->s_nrow-1;
  275. #else
  276.     wp->w_ntrows = term.t_nrow-1;        /* "-1" for mode line.    */
  277. #endif
  278.     wp->w_force = 0;
  279.     wp->w_flag  = WFMODE|WFHARD;        /* Full.        */
  280.  
  281.     /* first screen? */
  282.     if (first_screen == (SCREEN *)NULL) {
  283.         first_screen = sp;
  284.         return(sp);
  285.     }
  286.  
  287.     /* insert it at the tail of the screen list */
  288.     last_sp = first_screen;
  289.     while (last_sp->s_next_screen != (SCREEN *)NULL)
  290.         last_sp = last_sp->s_next_screen;
  291.     last_sp->s_next_screen = sp;
  292.  
  293.     /* and return the new screen pointer */
  294.     return(sp);
  295. }
  296.  
  297. SCREEN *PASCAL NEAR lookup_screen(scr_name)
  298.  
  299. char *scr_name;        /* named screen to find */
  300.  
  301. {
  302.     SCREEN *result;
  303.  
  304.     /* scan the screen list */
  305.     result = first_screen;
  306.     while (result) {
  307.  
  308.         /* if this is it, return its handle! */
  309.         if (strcmp(scr_name, result->s_screen_name) == 0)
  310.             return(result);
  311.  
  312.         /* on to the next screen */
  313.         result = result->s_next_screen;
  314.     }
  315.  
  316.     /* we didn't find it..... */
  317.     return((SCREEN *)NULL);
  318. }
  319.  
  320. int PASCAL NEAR select_screen(sp, announce)
  321.  
  322. SCREEN *sp;    /* ptr to screen to switch to */
  323. int announce;    /* announce the selection? */
  324.  
  325. {
  326.     WINDOW *temp_wp;    /* backup of current window ptr (curwp) */
  327.     SCREEN *temp_screen;    /* temp ptr into screen list */
  328.  
  329.     /* make sure there is something here to set to! */
  330.     if (sp == (SCREEN *)NULL)
  331.         return(FALSE);
  332.  
  333.     /* nothing to do, it is already current */
  334.     if (sp == first_screen)
  335.         return(TRUE);
  336.  
  337.     /* deselect the current window */
  338. #if     WINDOW_MSWIN
  339.         curwp->w_flag |= WFMODE;
  340. #else
  341.     temp_wp = curwp;
  342.     curwp = (WINDOW *)NULL;
  343.     modeline(temp_wp);
  344.     updupd(TRUE);
  345.     curwp = temp_wp;
  346. #endif
  347.  
  348.     /* save the current screens concept of current window */
  349.     first_screen->s_cur_window = curwp;
  350. #if     WINDOW_MSWIN
  351.         /* in MSWIN, the term entries may (but not always) already
  352.        reflect the new screen's size and the s_n... stuff is always
  353.        kept up to date by vtinitscr */
  354.     vtscreen (sp);
  355. #else
  356.     first_screen->s_roworg = term.t_roworg;
  357.     first_screen->s_colorg = term.t_colorg;
  358.     first_screen->s_nrow = term.t_nrow;
  359.     first_screen->s_ncol = term.t_ncol;
  360. #endif
  361.  
  362.     /* re-order the screen list */
  363.     temp_screen = first_screen;
  364.     while (temp_screen->s_next_screen != (SCREEN *)NULL) {
  365.         if (temp_screen->s_next_screen == sp) {
  366.             temp_screen->s_next_screen = sp->s_next_screen;
  367.             break;
  368.         }
  369.         temp_screen = temp_screen->s_next_screen;
  370.     }
  371.     sp->s_next_screen = first_screen;
  372.     first_screen = sp;
  373.  
  374.     /* reset the current screen, window and buffer */
  375.     wheadp = first_screen->s_first_window;
  376.     curwp = first_screen->s_cur_window;
  377.     curbp = curwp->w_bufp;
  378.  
  379.     /* let the display driver know we need a full screen update */
  380. #if     WINDOW_MSWIN
  381.         term.t_topscr (first_screen);
  382.         curwp->w_flag |= WFMODE;
  383.         update(FALSE);
  384. #else
  385.     update_size();
  386.     upwind();
  387. #endif
  388.     if (announce) {
  389.         mlwrite(TEXT225, first_screen->s_screen_name);
  390. /*            "[Switched to screen %s]" */
  391.     }
  392.     return(TRUE);
  393. }
  394.  
  395. /*    Build and popup a buffer containing the list of all screens.
  396.     Bound to "A-B".
  397. */
  398.  
  399. PASCAL NEAR list_screens(f, n)
  400.  
  401. int f,n;    /* prefix flag and argument */
  402.  
  403. {
  404.     register int status;    /* stutus return */
  405.  
  406.     if ((status = screenlist(f)) != TRUE)
  407.         return(status);
  408.     return(wpopup(slistp));
  409. }
  410.  
  411.  
  412. /*
  413.  * This routine rebuilds the
  414.  * text in the special secret buffer
  415.  * that holds the screen list. It is called
  416.  * by the list screens command. Return TRUE
  417.  * if everything works. Return FALSE if there
  418.  * is an error (if there is no memory). Iflag
  419.  * indecates weather to list hidden screens.
  420.  */
  421. PASCAL NEAR screenlist(iflag)
  422.  
  423. int iflag;    /* list hidden screen flag */
  424.  
  425. {
  426.     SCREEN *sp;        /* ptr to current screen to list */
  427.     WINDOW *wp;        /* ptr into current screens window list */
  428.     int status;        /* return status from functions */
  429.     char line[NSTRING];    /* buffer to construct list lines */
  430.     char bname[NSTRING];    /* name of next buffer */
  431.  
  432.     /* mark this buffer as unchanged so... */
  433.     slistp->b_flag &= ~BFCHG;
  434.  
  435.     /* we can dump it's old contents without complaint */
  436.     if ((status = bclear(slistp)) != TRUE)
  437.         return(status);
  438.  
  439.     /* there is no file connected with this buffer */
  440.     strcpy(slistp->b_fname, "");
  441.  
  442.     /* construct the header of this list */
  443.     if (addline(slistp, "Screen         Buffers") == FALSE
  444.      || addline(slistp, "------         -------") == FALSE)
  445.         return(FALSE);
  446.  
  447.     /* starting from the first screen */
  448.     sp = first_screen;
  449.  
  450.     /* scan all the screens */
  451.     while (sp) {
  452.  
  453.         /* construct the screen name */
  454.         strcpy(line, sp->s_screen_name);
  455.         strcat(line, "                ");
  456.         line[15] = 0;
  457.  
  458.         /* list this screens windows's buffer names */
  459.         wp = sp->s_first_window;
  460.         while (wp) {
  461.  
  462.             /* grab this window's buffer name */
  463.             strcpy(bname, wp->w_bufp->b_bname);
  464.  
  465.             /* handle full lines */
  466.             if (strlen(line) + strlen(bname) + 1 > 78) {
  467.                 if (addline(slistp, line) == FALSE)
  468.                     return(FALSE);
  469.                 strcpy(line, "               ");
  470.             }
  471.  
  472.             /* append this buffer name */
  473.             if (strlen(line) > 15)
  474.                 strcat(line, " ");
  475.             strcat(line, bname);
  476.  
  477.             /* on to the next window */
  478.             wp = wp->w_wndp;
  479.         }
  480.  
  481.         /* and add the line to the buffer */
  482.         if (addline(slistp, line) == FALSE)
  483.             return(FALSE);
  484.  
  485.         /* on to the next screen */
  486.         sp = sp->s_next_screen;
  487.     }
  488.  
  489.     /* all constructed! */
  490.     return(TRUE);
  491. }
  492.  
  493. /* rename_screen:    change the current screen's name    */
  494.  
  495. int PASCAL NEAR rename_screen(f, n)
  496.  
  497. int f, n;    /* default number and arguments */
  498.  
  499. {
  500.     char scr_name[NSTRING];  /* buffer to hold screen name */
  501.     int result;
  502.  
  503.     /* get the new name of the screen */
  504.     if ((result = mlreply(TEXT335, scr_name, NSTRING)) != TRUE) {
  505. /*                  "Change screen name to: " */
  506.         return(result);
  507.     } 
  508.  
  509.     if (lookup_screen(scr_name) != (SCREEN*)NULL) {
  510.         mlwrite(TEXT336);
  511. /*            "[Screen name already in use]" */
  512.         return(FALSE);
  513.     }
  514.  
  515.     /* replace the old screen name with the new */
  516.     free(first_screen->s_screen_name);
  517.     first_screen->s_screen_name = copystr(scr_name);
  518. #if    WINDOW_MSWIN
  519.     SetWindowText(first_screen->s_drvhandle, scr_name);
  520. #endif
  521.     return(TRUE);
  522.  
  523. }
  524.  
  525.  
  526.